package cn.ffcs.base.dao;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;

import cn.ffcs.base.model.BaseEntity;
import cn.ffcs.base.web.PageControl;
import cn.ffcs.util.ext.Expression;

/**
 * 
 * 扩展的基础DAO：
 *   主要实现查询的翻页优化等功能，通过自定义HQL实现<br/> <table>
 * <tr>
 * <td>负责人/principal: </td>
 * <td colspan="2">liuzhh</td>
 * <tr>
 * <td>修改记录/revision:</td>
 * <td colspan="2"></td>
 * </tr>
 * <tr>
 * <td>日期:</td>
 * <td>修改人:</td>
 * <td>修改说明:</td>
 * </tr>
 * <tr>
 * <td></td>
 * <td></td>
 * <td></td>
 * </tr>
 * </table>
 * @author liuzhh
 * @version $Id$
 */
public class ExtBaseDAO<B extends BaseEntity> extends BaseDAO<B>
{
    
    /**
     * 
     * 获取泛型实体类
     * @return
     */
    private Class<B> getEntityClass(){
        return (Class<B>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
    }
    
    /**
     * 按条件查询翻页
     * @param cond
     * @param currPage
     * @param pageSize
     * @return
     */
    @SuppressWarnings("unchecked")
    public PageControl findByPage(Criterion cond,int currPage, int pageSize)
    {
        
        //获取总数的hql和获取结果的hql
    	
        String countHql=getCountHql(cond);      
        //事务开始
        Session session=getSession();
        System.out.println("查询条数："+countHql);
        //获取数据总数
        Query query=session.createQuery(countHql);
        List lCount=query.list();
        long lc=(Long)lCount.get(0);
        int count=(int)lc;
        //初始化翻页
        PageControl pageControl=new PageControl(count,currPage,pageSize);
        final int startRow = pageControl.getStart();
        final int endRow=pageControl.getPageSize();  
        String resultHql=getPageQueryHql(cond,startRow,endRow);
        //获取结果集
        List results=null;
        String en = getEntityName();
        en = en.substring(en.lastIndexOf(".") + 1, en.length());
        results = session.createQuery(resultHql).setFirstResult(startRow)
                .setMaxResults(endRow).list(); 
        
        //释放连接
        this.releaseSession(session);
        
        return new PageControl(results, startRow, pageSize, currPage,
                pageControl.getTotalPage(), pageControl.getTotal());
 
    	
    }
    
    public PageControl findByPage(Expression exp,int currPage, int pageSize)
    {
        
        //获取总数的hql和获取结果的hql
        String countHql=getCountExpHql(exp);      
        //事务开始
        Session session=getSession();

        //获取数据总数
        Query query=session.createQuery(countHql);
        List lCount=query.list();
        long lc=(Long)lCount.get(0);
        int count=(int)lc;
        //初始化翻页
        PageControl pageControl=new PageControl(count,currPage,pageSize);
        final int startRow = pageControl.getStart();
        final int endRow=pageControl.getPageSize();  
        String resultHql=getPageQueryExtHql(exp,startRow,endRow);
        //获取结果集
        List results=null;
        String en = getEntityName();
        en = en.substring(en.lastIndexOf(".") + 1, en.length());
        results = session.createQuery(resultHql).setFirstResult(startRow)
                .setMaxResults(endRow).list(); 
        
        //释放连接
        this.releaseSession(session);
        
        return new PageControl(results, startRow, pageSize, currPage,
                pageControl.getTotalPage(), pageControl.getTotal());

    } 
    
    /**
     * 
     * 生成总数的hql
     * @param baseEntity
     * @return
     */
    protected String getCountHql(Criterion cond){
        String en=this.getEntityName();
        en=en.substring(en.lastIndexOf(".")+1, en.length());
        String result="select count("+en.toLowerCase()+".id) from "+en+" "+en.toLowerCase();

        if (cond!=null){
            String conds=" where "+cond.toString();
            result+=conds;
        }
        
        return result;
    }
    
    protected String getCountExpHql(Expression exp){
        String en=this.getEntityName();
        en=en.substring(en.lastIndexOf(".")+1, en.length());
        String result="select count("+en.toLowerCase()+".id) from "+en+" "+en.toLowerCase();

        if (exp!=null && exp.getSqlString()!=null ){
            String conds=" where "+exp.getSqlString();
            result+=conds;
        }
        
        return result;
    }
    
    /**
     * 
     * 生成翻页的hql
     * @param baseEntity
     * @return
     */
    protected String getPageQueryHql(Criterion cond,int startRow,int endRow){
        String en=this.getEntityName();
        en=en.substring(en.lastIndexOf(".")+1, en.length());
    
        String  result="from "+en+"  ";
        
        if (cond!=null){
            String conds=" where "+cond.toString();
            result+=conds;
        }    
        
        return result;
    }
    protected String getPageQueryExtHql(Expression exp,int startRow,int endRow){
        String en=this.getEntityName();
        en=en.substring(en.lastIndexOf(".")+1, en.length());
    
        String  result="from "+en+"  ";
        
        if (exp!=null && exp.getSqlString()!=null){
            String conds=" where "+exp.getSqlString();
            result+=conds;
        }    
        
        return result;
    }

}
